#pragma once

#include "comm/my_str.h"

#define MY_HTTP_MAX_LINE_LENGTH                 4096
#define MY_HTTP_MIN_WRITEABLE_SIZE              128
#define MY_HTTP_MAX_WRITE_IOV                   4

// http scheme
#define MY_SCHEME_HTTP                          "http"
#define MY_SCHEME_HTTP_LEN                      (sizeof("http") - 1)
#define MY_SCHEME_HTTPS                         "https"
#define MY_SCHEME_HTTPS_LEN                     (sizeof("https") - 1)

// http version
#define MY_HTTP_VERSION_9                       9
#define MY_HTTP_VERSION_10                      1000
#define MY_HTTP_VERSION_11                      1001
#define MY_HTTP_VERSION_20                      2000
#define MY_HTTP_VERSION_QUIC                    3000

// http response status
#define MY_HTTP_CONTINUE                        100
#define MY_HTTP_SWITCHING_PROTOCOLS             101
#define MY_HTTP_PROCESSING                      102

#define MY_HTTP_OK                              200
#define MY_HTTP_CREATED                         201
#define MY_HTTP_ACCEPTED                        202
#define MY_HTTP_NO_CONTENT                      204
#define MY_HTTP_PARTIAL_CONTENT                 206

#define MY_HTTP_MULTIPLE_CHOICES                300
#define MY_HTTP_MOVED_PERMANENTLY               301
#define MY_HTTP_MOVED_TEMPORARILY               302
#define MY_HTTP_NOT_MODIFIED                    304
#define MY_HTTP_TEMPORARY_REDIRECT              307
#define MY_HTTP_PERMANENT_REDIRECT              308

#define MY_HTTP_BAD_REQUEST                     400
#define MY_HTTP_UNAUTHORIZED                    401
#define MY_HTTP_FORBIDDEN                       403
#define MY_HTTP_NOT_FOUND                       404
#define MY_HTTP_NOT_ALLOWED                     405
#define MY_HTTP_REQUEST_TIME_OUT                408
#define MY_HTTP_LENGTH_REQUIRED                 411
#define MY_HTTP_REQUEST_ENTITY_TOO_LARGE        413
#define MY_HTTP_REQUEST_URI_TOO_LARGE           414
#define MY_HTTP_RANGE_NOT_SATISFIABLE           416
#define MY_HTTP_TOO_MANY_REQUESTS               429

#define MY_HTTP_INTERNAL_SERVER_ERROR           500
#define MY_HTTP_NOT_IMPLEMENTED                 501
#define MY_HTTP_BAD_GATEWAY                     502
#define MY_HTTP_SERVICE_UNAVAILABLE             503
#define MY_HTTP_GATEWAY_TIME_OUT                504
#define MY_HTTP_VERSION_NOT_SUPPORTED           505

#define MY_HTTP_STATUS_CODE_END                 999

// http header
#define MY_HTTP_HOST_HDR                        "Host"
#define MY_HTTP_HOST_HDR_LEN                    (sizeof(MY_HTTP_HOST_HDR) - 1)
#define MY_HTTP_CONNECTION_HDR                  "Connection"
#define MY_HTTP_CONNECTION_HDR_LEN              (sizeof(MY_HTTP_CONNECTION_HDR) - 1)
#define MY_HTTP_CL_HDR                          "Content-Length"
#define MY_HTTP_CL_HDR_LEN                      (sizeof(MY_HTTP_CL_HDR) - 1)
#define MY_HTTP_RANGE_HDR                       "Range"
#define MY_HTTP_RANGE_HDR_LEN                   (sizeof(MY_HTTP_RANGE_HDR) - 1)
#define MY_HTTP_TE_HDR                          "Transfer-Encoding"
#define MY_HTTP_TE_HDR_LEN                      (sizeof(MY_HTTP_TE_HDR) - 1)

/* http header value */
#define MY_HTTP_CLOSE                           "close"
#define MY_HTTP_CLOSE_LEN                       (sizeof(MY_HTTP_CLOSE) - 1)
#define MY_HTTP_CHUNKED                         "chunked"
#define MY_HTTP_CHUNKED_LEN                     (sizeof(MY_HTTP_CHUNKED) - 1)
#define MY_HTTP_IDENTITY                        "identity"
#define MY_HTTP_IDENTITY_LEN                    (sizeof(MY_HTTP_IDENTITY) - 1)
#define MY_HTTP_KEEPALIVE                       "keep-alive"
#define MY_HTTP_KEEPALIVE_LEN                   (sizeof(MY_HTTP_KEEPALIVE) - 1)

/* http version */
#define MY_HTTP_VERSION_PERFIX                  "HTTP/"
#define MY_HTTP_VERSION_PERFIX_LEN              (sizeof(MY_HTTP_VERSION_PERFIX) - 1)
#define MY_HTTP_VERSION_10_STR                  "HTTP/1.0"
#define MY_HTTP_VERSION_10_STR_LEN              (sizeof(MY_HTTP_VERSION_10_STR) - 1)
#define MY_HTTP_VERSION_11_STR                  "HTTP/1.1"
#define MY_HTTP_VERSION_11_STR_LEN              (sizeof(MY_HTTP_VERSION_11_STR) - 1)

/* http error */
#define MY_HTTP_READLINE_FAILED                 1001
#define MY_HTTP_INVALID_HEADER_LINE             1002
#define MY_HTTP_INVALID_REQUEST_URI             1003
#define MY_HTTP_INVALID_REQUEST_LINE            1004
#define MY_HTTP_INVALID_HTTP_VERSION            1005
#define MY_HTTP_INVALID_CONNECT_SCHEME          1006
#define MY_HTTP_INVALID_CHUNK_LINE              1007
#define MY_HTTP_REQUEST_HEADER_TOO_LARGER       1008
#define MY_HTTP_REQUIRE_HOST_HDR                1009
#define MY_HTTP_INVALID_CONTENT_LENGTH          1010
#define MY_HTTP_INVALID_TRANSFER_ENCODING       1011
#define MY_HTTP_READ_REQUEST_BODY_TIMEOUT       1012
#define MY_HTTP_READ_AFTER_BODY_DATA_TIMEOUT    1013
#define MY_HTTP_READ_AFTER_BODY_DATA_FAILED     1014
#define MY_HTTP_REQUEST_HAS_ERROR               1015
#define MY_HTTP_INVALID_RESPONSE_STATUS_CODE    1016
#define MY_HTTP_ALREADY_SEND_SPECIAL_RESPONSE   1017
#define MY_HTTP_SEND_RESPONSE_BODY_TIMEOUT      1018
#define MY_HTTP_INVALID_CONTENT_LENGTH_HDR      1019
#define MY_HTTP_INVALID_TE_HEADER               1020
#define MY_HTTP_NOT_ALLOWED_TE_HDR              1021
#define MY_HTTP_INVALID_REQUEST_METHOD          1022
#define MY_HTTP_NO_SUPPORT_H9                   1023
#define MY_HTTP_SEND_REQUEST_BODY_TIMEOUT       1024
#define MY_HTTP_RESPONSE_HEADER_TOO_LARGER      1025
#define MY_HTTP_INVALID_RESPONSE_LINE           1026
#define MY_HTTP_SEND_RESPONSE_TERMINATED        1027
#define MY_HTTP_READ_REQUEST_TERMINATED         1028
#define MY_HTTP_SEND_REQUEST_TERMINATED         1029
#define MY_HTTP_READ_RESPONSE_TERMINATED        1030


extern my_str_t my_http_host_hdr_name;
extern my_str_t my_http_connection_hdr_name;
extern my_str_t my_http_cl_hdr_name;
extern my_str_t my_http_range_hdr_name;
extern my_str_t my_http_te_hdr_name;

extern my_str_t my_http_version_10_str;
extern my_str_t my_http_version_11_str;

my_str_t *my_http_get_response_reason(int status_code);


static inline my_bool_t
my_http_method_is_head(my_str_t str)
{
    if (str.len == 4 && 
        str.data[0] == 'H' &&
        str.data[1] == 'E' &&
        str.data[2] == 'A' &&
        str.data[3] == 'D') {
        return MY_TRUE;
    }

    return MY_FALSE;
}


static inline my_bool_t
my_http_method_is_get(my_str_t str)
{
    if (str.len == 3 &&
        str.data[0] == 'G' &&
        str.data[1] == 'E' &&
        str.data[2] == 'T') {
        return MY_TRUE;
    }

    return MY_FALSE;
}